//
//  MGBaseAccessor.m
//  MoneyGoal_iOS
//
//  Created by yyb on 2022/9/3.
//  Copyright © 2022 Moneyease CO,. LTD. All rights reserved.
//

#import "MGBaseAccessor.h"

@implementation MGBaseAccessor

+ (MGBaseAccessor *)shared
{
    static MGBaseAccessor *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[MGBaseAccessor alloc] init];
    });
    return manager;
}

- (instancetype)init
{
    self = [super init];
    if (!self) return nil;
    
    self.dataModels = [NSMutableArray new];
    
    return self;
}

- (Class)getAccessorClass
{
    return [NSObject class];
}

- (NSString *)getAccessorDirPath
{
    return @"";
}

- (BOOL)shouldInitialize
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    BOOL isInited = [[defaults objectForKey:[self getAccessorDirPath]] boolValue];
    if (!isInited) {
        [defaults setBool:YES forKey:[self getAccessorDirPath]];
        return YES;
    }
    return NO;
}

- (NSString *)getOssPrefix
{
    return @"";
}

// =================================================================
- (void)getLocalDataModels
{
    Class dataClass = [self getAccessorClass];
    NSString *dirPath = [MGFileManager.shared directoryWithSubPath:[self getAccessorDirPath]];
    NSArray *subPaths = [NSFileManager.defaultManager subpathsAtPath:dirPath];
    
    NSMutableArray *dataModels = [[NSMutableArray alloc] init];
    for (NSString *subPath in subPaths) {
        NSString *_subPath = [dirPath stringByAppendingPathComponent:subPath];
        NSData *data = [NSFileManager.defaultManager contentsAtPath:_subPath];
        if (data) {
            id dataModel = [dataClass yy_modelWithJSON:data];
            [dataModels addObject:dataModel];
        }
    }
    self.dataModels = dataModels;
    
    if (self.shouldInitialize) {
        NSString *path = [NSBundle.mainBundle pathForResource:[self getAccessorDefaultPath] ofType:@"txt"];
        NSData *data = [NSFileManager.defaultManager contentsAtPath:path];
        if (data) {
            self.dataModels = [NSArray yy_modelArrayWithClass:dataClass json:data].mutableCopy;
            [self saveToLocalWithDataModels:self.dataModels completeBlock:nil];
        }
    }
}

- (void)getOssAndSaveDataModelsWithCompleteBlock:(YYBEmptyCompleteBlock)completeBlock errorBlock:(YYBErrorBlock)errorBlock
{
    [MGOssManager.shared getDataModelsWithPrefix:[self getOssPrefix] dataClass:[self getAccessorClass] completeBlock:^(NSArray * _Nonnull dataModels) {
        if (dataModels) {
            dispatch_async_on_main_queue(^{
                [self saveToLocalWithDataModels:dataModels completeBlock:^{
                    if (completeBlock) {
                        completeBlock();
                    }
                }];
            });
        }
    } errorBlock:^(NSError *error) {
        dispatch_async_on_main_queue(^{
            if (errorBlock) {
                errorBlock(error);
            }
        });
    }];
}

// 上传数据到阿里OSS
- (void)saveToOssAndLocalWithDataModels:(NSArray *)dataModels completeBlock:(YYBEmptyCompleteBlock)completeBlock errorBlock:(YYBErrorBlock)errorBlock
{
    if ([MGOssManager shouldUpload]) {
        [MGOssManager.shared saveToOssWithDataModels:dataModels completeBlock:^{
            dispatch_async_on_main_queue(^{
                // 保存到本地
                [self saveToLocalWithDataModels:dataModels completeBlock:completeBlock];
            });
        } errorBlock:^(NSError *error) {
            // 失败了还是需要保存到本地的
            dispatch_async_on_main_queue(^{
                [self saveToLocalWithDataModels:dataModels completeBlock:completeBlock];
                if (errorBlock) {
                    errorBlock(error);
                }
            });
        }];
    } else {
        [self saveToLocalWithDataModels:dataModels completeBlock:completeBlock];
    }
}

- (void)saveAllToOssWithCompleteBlock:(YYBEmptyCompleteBlock)completeBlock errorBlock:(YYBErrorBlock)errorBlock
{
    [self saveToOssWithDataModels:self.dataModels completeBlock:completeBlock errorBlock:errorBlock];
}

- (void)saveToOssWithDataModels:(NSArray *)dataModels completeBlock:(YYBEmptyCompleteBlock)completeBlock errorBlock:(YYBErrorBlock)errorBlock
{
    if ([MGOssManager shouldUpload]) {
        [MGOssManager.shared saveToOssWithDataModels:dataModels completeBlock:^{
            dispatch_async_on_main_queue(^{
                if (completeBlock) {
                    completeBlock();
                }
            });
        } errorBlock:^(NSError *error) {
            dispatch_async_on_main_queue(^{
                if (errorBlock) {
                    errorBlock(error);
                }
            });
        }];
    }
}

- (void)deleteOssDataModel:(MGAccessorModel *)dataModel completeBlock:(YYBEmptyCompleteBlock)completeBlock errorBlock:(YYBErrorBlock)errorBlock
{
    if ([MGOssManager shouldUpload]) {
        [MGOssManager.shared deleteObjectKey:dataModel.getOssKey completeBlock:^{
            dispatch_async_on_main_queue(^{
                if (completeBlock) {
                    completeBlock();
                }
            });
        } errorBlock:^(NSError *error) {
            dispatch_async_on_main_queue(^{
                if (errorBlock) {
                    errorBlock(error);
                }
            });
        }];
    } else {
        if (completeBlock) {
            completeBlock();
        }
    }
}

// =========================================================================
// 保存数组到本地
- (void)saveToLocalWithDataModels:(NSArray *)dataModels completeBlock:(YYBTapedActionBlock)completeBlock
{
    NSString *dirPath = [MGFileManager.shared directoryWithSubPath:[self getAccessorDirPath]];
    for (MGAccessorModel *dataModel in dataModels) {
        NSData *data = [dataModel yy_modelToJSONData];
        if (data) {
            NSString *uniqueId = [NSString stringWithFormat:@"%@:%@",@(dataModel.uniqueId), @(dataModel.pathUniqueId)];
            NSString *dataModelPath = [dirPath stringByAppendingPathComponent:uniqueId];
            
            [data writeToFile:dataModelPath atomically:YES];
        }
    }
    if (completeBlock) {
        completeBlock();
    }
}

- (void)createDataModel:(MGAccessorModel *)dataModel completeBlock:(YYBTapedActionBlock)completeBlock errorBlock:(YYBErrorBlock)errorBlock
{
    [self.dataModels insertObject:dataModel atIndex:0];
    [self saveToOssAndLocalWithDataModels:@[dataModel] completeBlock:completeBlock errorBlock:errorBlock];
}

// 如果登录，只有线上删除成功后，才能删除本地数据
- (void)deleteDataModel:(MGAccessorModel *)dataModel completeBlock:(nullable YYBTapedActionBlock)completeBlock errorBlock:(nullable YYBErrorBlock)errorBlock
{
    // 删除oss的数据，如果没有开启数据交互的功能，直接会回调completeBlock
    [self deleteOssDataModel:dataModel completeBlock:^{
        dispatch_async_on_main_queue(^{
            [self.dataModels removeObject:dataModel];
            // 删除本地的数据
            [self deleteLocalDataModel:dataModel completeBlock:completeBlock errorBlock:errorBlock];
        });
    } errorBlock:errorBlock];
}

- (void)deleteLocalDataModel:(MGAccessorModel *)dataModel completeBlock:(nullable YYBTapedActionBlock)completeBlock errorBlock:(nullable YYBErrorBlock)errorBlock
{
    if (dataModel) {
        NSString *dirPath = [MGFileManager.shared directoryWithSubPath:[self getAccessorDirPath]];
        NSString *uniqueId = [NSString stringWithFormat:@"%@:%@",@(dataModel.uniqueId), @(dataModel.pathUniqueId)];
        NSString *dataModelPath = [dirPath stringByAppendingPathComponent:uniqueId];
        
        NSError *error = nil;
        [NSFileManager.defaultManager removeItemAtPath:dataModelPath error:&error];
        if (error && errorBlock) {
            errorBlock(error);
        } else {
            if (completeBlock) {
                completeBlock();
            }
        }
    }
}

- (void)updateDataModel:(MGAccessorModel *)dataModel shouldUpdateModel:(nonnull MGAccessorModel *)shouldUpdateModel completeBlock:(nullable YYBEmptyCompleteBlock)completeBlock errorBlock:(nullable YYBErrorBlock)errorBlock
{
    NSInteger index = [self.dataModels indexOfObject:dataModel];
    [self.dataModels replaceObjectAtIndex:index withObject:shouldUpdateModel];
    
    [self saveToOssAndLocalWithDataModels:@[shouldUpdateModel] completeBlock:^{
        dispatch_async_on_main_queue(^{
            if (completeBlock) {
                completeBlock();
            }
        });
    } errorBlock:^(NSError *error) {
        dispatch_async_on_main_queue(^{
            if (errorBlock) {
                errorBlock(error);
            }
        });
    }];
}

- (void)clearAllLocalDataWithCompleteBlock:(YYBTapedActionBlock)completeBlock errorBlock:(nullable YYBErrorBlock)errorBlock
{
    // 默认的不能被删除
    NSArray *_waitDeleteObjs = [self.dataModels takeWhile:^BOOL(MGAccessorModel *obj) {
        return !obj.isStatic;
    }];
    
    NSArray *_objs = [self.dataModels takeWhile:^BOOL(MGAccessorModel *obj) {
        return obj.isStatic;
    }];
    
    NSArray *_waitDeleteSubPaths = [_waitDeleteObjs map:^id(MGAccessorModel *obj, NSInteger index) {
        NSString *uniqueId = [NSString stringWithFormat:@"%@:%@",@(obj.uniqueId), @(obj.pathUniqueId)];
        return uniqueId;
    }];
    
    // 剩余默认的数据
    self.dataModels = _objs.mutableCopy;
    
    NSString *dirPath = [MGFileManager.shared directoryWithSubPath:[self getAccessorDirPath]];
    for (NSString *subPath in _waitDeleteSubPaths) {
        NSError *error = nil;
        NSString *_subPath = [dirPath stringByAppendingPathComponent:subPath];
        [NSFileManager.defaultManager removeItemAtPath:_subPath error:&error];
        if (error && errorBlock) {
            errorBlock(error);
            return;
        }
    }
    
    if (completeBlock) {
        completeBlock();
    }
}

@end
